#!/usr/bin/env python
"""
Celery Beat定时调度器
管理定时任务的执行
"""
import os
import sys
import signal
import logging
from pathlib import Path
from datetime import timedelta

# 添加项目路径
sys.path.insert(0, str(Path(__file__).parent.parent))

from src.celery_app import app
from src.utils.logging_config import setup_logging
from celery.schedules import crontab

# 设置日志
logger = setup_logging('celery_beat')

class BeatScheduler:
    """Beat调度器管理"""
    
    def __init__(self):
        self.beat = None
        self.setup_signal_handlers()
        self.configure_schedules()
        
    def setup_signal_handlers(self):
        """设置信号处理器"""
        signal.signal(signal.SIGTERM, self.handle_shutdown)
        signal.signal(signal.SIGINT, self.handle_shutdown)
        
    def handle_shutdown(self, signum, frame):
        """优雅关闭"""
        logger.info(f"Received signal {signum}, shutting down beat...")
        sys.exit(0)
        
    def configure_schedules(self):
        """配置定时任务调度规则"""
        # 爬虫任务调度配置
        crawler_schedules = {
            # 微博热搜 - 每15分钟
            'crawl-weibo-hot': {
                'task': 'src.tasks.crawler.crawl_weibo',
                'schedule': timedelta(minutes=15),
                'options': {
                    'queue': 'crawler_queue',
                    'priority': 8,
                    'expires': 600  # 10分钟过期
                }
            },
            
            # 知乎热榜 - 每30分钟
            'crawl-zhihu-hot': {
                'task': 'src.tasks.crawler.crawl_zhihu',
                'schedule': timedelta(minutes=30),
                'options': {
                    'queue': 'crawler_queue',
                    'priority': 7,
                    'expires': 1200
                }
            },
            
            # 头条热点 - 每20分钟
            'crawl-toutiao-hot': {
                'task': 'src.tasks.crawler.crawl_toutiao',
                'schedule': timedelta(minutes=20),
                'options': {
                    'queue': 'crawler_queue',
                    'priority': 7,
                    'expires': 900
                }
            },
            
            # 百度热搜 - 每15分钟
            'crawl-baidu-hot': {
                'task': 'src.tasks.crawler.crawl_baidu',
                'schedule': timedelta(minutes=15),
                'options': {
                    'queue': 'crawler_queue',
                    'priority': 8,
                    'expires': 600
                }
            },
            
            # 小红书 - 每45分钟
            'crawl-xiaohongshu-hot': {
                'task': 'src.tasks.crawler.crawl_xiaohongshu',
                'schedule': timedelta(minutes=45),
                'options': {
                    'queue': 'crawler_queue',
                    'priority': 6,
                    'expires': 1800
                }
            },
            
            # 抖音 - 每30分钟
            'crawl-douyin-hot': {
                'task': 'src.tasks.crawler.crawl_douyin',
                'schedule': timedelta(minutes=30),
                'options': {
                    'queue': 'crawler_queue',
                    'priority': 7,
                    'expires': 1200
                }
            },
            
            # Twitter - 每小时
            'crawl-twitter-hot': {
                'task': 'src.tasks.crawler.crawl_twitter',
                'schedule': crontab(minute=0),  # 每小时整点
                'options': {
                    'queue': 'crawler_queue',
                    'priority': 6,
                    'expires': 2400
                }
            },
            
            # Reddit - 每小时
            'crawl-reddit-hot': {
                'task': 'src.tasks.crawler.crawl_reddit',
                'schedule': crontab(minute=30),  # 每小时半点
                'options': {
                    'queue': 'crawler_queue',
                    'priority': 6,
                    'expires': 2400
                }
            },
            
            # YouTube - 每2小时
            'crawl-youtube-hot': {
                'task': 'src.tasks.crawler.crawl_youtube',
                'schedule': crontab(minute=0, hour='*/2'),  # 每2小时
                'options': {
                    'queue': 'crawler_queue',
                    'priority': 5,
                    'expires': 3600
                }
            },
            
            # 健康检查 - 每5分钟
            'health-check': {
                'task': 'src.tasks.health.health_check',
                'schedule': timedelta(minutes=5),
                'options': {
                    'queue': 'health_queue',
                    'priority': 9,
                    'expires': 240
                }
            },
            
            # 数据新鲜度检查 - 每30分钟
            'data-freshness-check': {
                'task': 'src.tasks.health.check_data_freshness',
                'schedule': timedelta(minutes=30),
                'options': {
                    'queue': 'health_queue',
                    'priority': 8,
                    'expires': 1200
                }
            },
            
            # 清理过期任务 - 每天凌晨3点
            'cleanup-expired-tasks': {
                'task': 'src.tasks.scheduler.cleanup_expired_tasks',
                'schedule': crontab(hour=3, minute=0),
                'options': {
                    'queue': 'scheduler_queue',
                    'priority': 5
                }
            },
            
            # 生成统计报告 - 每天早上9点
            'generate-daily-report': {
                'task': 'src.tasks.scheduler.generate_daily_report',
                'schedule': crontab(hour=9, minute=0),
                'options': {
                    'queue': 'scheduler_queue',
                    'priority': 6
                }
            }
        }
        
        # 更新应用配置
        app.conf.beat_schedule.update(crawler_schedules)
        
        # 设置时区
        app.conf.timezone = 'Asia/Shanghai'
        
        logger.info(f"Configured {len(crawler_schedules)} scheduled tasks")
        
    def start_beat(self, loglevel='INFO'):
        """
        启动Beat调度器
        
        Args:
            loglevel: 日志级别
        """
        beat_args = [
            'beat',
            '--loglevel', loglevel,
            '--pidfile', '/var/run/celery/beat.pid',
            '--schedule', '/var/run/celery/celerybeat-schedule',
        ]
        
        logger.info(f"Starting Celery beat with args: {beat_args}")
        app.start(argv=beat_args)

def main():
    """主函数"""
    import argparse
    
    parser = argparse.ArgumentParser(description='Celery Beat Scheduler')
    parser.add_argument('--loglevel', default='INFO', help='Log level')
    
    args = parser.parse_args()
    
    scheduler = BeatScheduler()
    scheduler.start_beat(loglevel=args.loglevel)

if __name__ == '__main__':
    main()